#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include "myFramework.h"
#include "CGdemo.h"
#include <Cg/cg.h>
#include <Cg/cgGL.h>
#include "Graphics/CGShaderProgram.h"

Image *g_img = NULL;
Texture *g_texture = NULL, *g_texRT = NULL;
RenderTarget *g_renderTarget = NULL;
Mesh *g_model = NULL;
Camera *g_rtCamera = NULL;

using namespace std;
using namespace glm;

APP_MAIN_IMPLEMENTATION(CGDemo);

void CGDemo::Render2D(double timeElapsed)
{
  RayFrame::Configure::InstanceRef().SetValueNum(SHOW_DEBUG_INFO, 1);
  __super::Render2D(timeElapsed);
}

void CGDemo::Render(double timeElapsed)
{
  m_renderer->Clear(BLACK);
  m_camera->Look();

  m_cgProgram->SetShaderParam("modelViewProj", g_App->GetCamera()->GetMatrixViewModelProjection());
  m_cgProgram->SetShaderParam("color", glm::vec3(1,0,0));
  m_cgProgram->Begin();

  m_renderer->SetColor(WHITE);

  DrawCube();
  DrawGrid();

  m_cgProgram->End();
}

CGDemo::CGDemo()
{

}

void CGDemo::InitApp()
{
  __super::InitApp();
  // create a extra camera for fbo
  g_rtCamera = m_renderer->CreateCamera();

  loadShaders();
}

// save fbo to a image while pressing "c"
bool CGDemo::OnKey(unsigned key, bool down)
{

  return NATIVE_APP::OnKey(key, down);
}

void CGDemo::OnClose()
{

}

void CGDemo::checkError()
{
  CGerror error;
  const char *string = cgGetLastErrorString(&error);

  if (error != CG_NO_ERROR) 
  {
    printf("%s: %s: %s\n", string);
    if (error == CG_COMPILER_ERROR) 
    {
      const char* msg = cgGetLastListing(m_context);
      
      MessageBox(NULL, msg, "Compile error", MB_OK);
    }
    exit(1);
  }
}

unsigned long getFileLength(ifstream& file)
{
  if(!file.good()) return 0;

  unsigned long pos = (unsigned long) file.tellg();
  file.seekg(0,ios::end);
  unsigned long m_sourceLen = (unsigned long) file.tellg();
  file.seekg(ios::beg);

  return m_sourceLen;
}

void CGDemo::loadShaders()
{
  m_cgProgram = g_renderer->CreateCGShaderProgram();
  m_cgProgram->Create(
    "illum.cg", EMPTY_STRING);

//   m_context = cgCreateContext();
//   checkError();
// 
//   // Get The Latest GL Vertex Profile
//   m_profile = cgGLGetLatestProfile(CG_GL_VERTEX);
//   checkError();
// 
//   m_shaderProgram = cgCreateProgramFromFile(
//     m_context,
//     CG_SOURCE, 
//     "D:/proj/work/myFramework/Resources/Shaders/illum.cg",
//     m_profile, "main", NULL);
//   checkError();
// 
//   m_paramMvp = cgGetNamedParameter(m_shaderProgram, "modelViewProj");
//   checkError();
// 
//   cgGLLoadProgram(m_shaderProgram);
}
